package com.bestcem.xm.award.controller;

import com.alibaba.fastjson.JSON;
import com.bestcem.xm.award.controller.param.point.BandPointDrawParam;
import com.bestcem.xm.award.controller.param.point.PointAwardSaveParam;
import com.bestcem.xm.award.controller.param.point.PointAwardWinListParam;
import com.bestcem.xm.award.controller.vo.FileInfoVO;
import com.bestcem.xm.award.controller.vo.award.CreateAwardVO;
import com.bestcem.xm.award.controller.vo.award.UpdateAwardVO;
import com.bestcem.xm.award.controller.vo.point.BandPointDrawVO;
import com.bestcem.xm.award.controller.vo.point.PointAwardStatisVO;
import com.bestcem.xm.award.controller.vo.point.PointAwardVO;
import com.bestcem.xm.award.controller.vo.point.PointAwardWinListVO;
import com.bestcem.xm.award.service.PointAwardDrawService;
import com.bestcem.xm.award.service.bo.award.AwardAwardBO;
import com.bestcem.xm.award.service.bo.point.BandPointDrawBO;
import com.bestcem.xm.award.service.bo.point.PointAwardBO;
import com.bestcem.xm.award.service.bo.point.PointAwardStatisBO;
import com.bestcem.xm.award.service.bo.point.PointAwardWinListBO;
import com.bestcem.xm.award.service.dto.AwardDataDTO;
import com.bestcem.xm.award.service.dto.FileInfoDTO;
import com.bestcem.xm.award.service.dto.awardaward.CreateAwardDTO;
import com.bestcem.xm.award.service.dto.awardaward.GetAwardDTO;
import com.bestcem.xm.award.service.dto.awardaward.UpdateAwardDTO;
import com.bestcem.xm.award.service.impl.AwardDispatcher;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.domain.web.XmResultJson;
import com.bestcem.xm.common.core.uitls.StringUtil;
import com.bestcem.xm.component.security.context.SecurityContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;

import static com.bestcem.xm.award.constant.PointAwardConstant.FAIL_CODE;

/**
 * 品牌积分接口 新增、修改、删除、列表查询
 *
 * @author xa.zhang <xa.zhang@idiaoyan.com>
 * @version v1.0
 * @date 2021/8/17 14:17
 */
@Slf4j
@RestController
@RequestMapping(value = "/award/v3/awardpoint", produces = MediaType.APPLICATION_JSON_VALUE)
public class PointAwardController {

    @Resource
    private AwardDispatcher awardDispatcher;
    @Resource
    private PointAwardDrawService pointAwardDrawService;

    /**
     * 查询单个积分
     *
     * @param id id
     * @return 结果
     */
    @GetMapping("/{id}")
    XmResultJson<PointAwardVO> findById(@PathVariable("id") String id) {

        GetAwardDTO serviceGetAwardDTO = new GetAwardDTO();
        serviceGetAwardDTO.setNeedWin(false);
        serviceGetAwardDTO.setId(id);
        ServiceResult<AwardDataDTO> serviceGetResult = awardDispatcher.getAward(serviceGetAwardDTO);

        //最简单的就是最好的，之前的写的太复杂了
        if (serviceGetResult.isSuccess()) {
            AwardAwardBO award = serviceGetResult.getData().getAward();
            PointAwardVO pointAwardBO = PointAwardBO.createAwardVO(award);
            return XmResultJson.success(pointAwardBO);
        } else {
            return XmResultJson.fail(serviceGetResult.getErrorData(), serviceGetResult.getMsg());
        }
    }

    /**
     * 新增
     *
     * @param param 参数
     * @return 结果
     */
    @PostMapping
    public XmResultJson<CreateAwardVO> add(@RequestBody @Valid PointAwardSaveParam param, BindingResult errors) {

        param.setOrgId(SecurityContextHolder.getOrgId());

        log.info("add param:{}", param);
        if (param.getId() != null) {
            return XmResultJson.fail(FAIL_CODE, "新增不能带id");
        }
        StringBuilder errorStr = new StringBuilder();
        //判断是否有错误值
        if (errors.hasErrors()) {
            errors.getAllErrors().stream().forEach(error -> {
                errorStr.append(error.getDefaultMessage()).append(";");
            });
            if (errorStr.length() > 0) {
                errorStr.deleteCharAt(errorStr.length() - 1);
            }
            return XmResultJson.fail(FAIL_CODE, errorStr.toString());
        }

        AwardAwardBO awardAward = PointAwardSaveParam.createAward(param);
        if (log.isInfoEnabled()) {
            log.info("[award] 创建积分奖励:{}", JSON.toJSONString(awardAward));
        }

        CreateAwardDTO serviceParam = new CreateAwardDTO();
        serviceParam.setAwardAward(awardAward);

        ServiceResult<String> serviceResult = awardDispatcher.createAward(serviceParam);
        if (serviceResult.isSuccess()) {
            CreateAwardVO createAwardVO = new CreateAwardVO();
            createAwardVO.setId(serviceResult.getData());
            return XmResultJson.success(createAwardVO);
        } else {
            return XmResultJson.fail(serviceResult.getErrorData(), serviceResult.getMsg());
        }
    }

    /**
     * 修改
     *
     * @param param 参数
     * @return 结果
     */
    @PutMapping
    XmResultJson<UpdateAwardVO> updateById(@RequestBody @Valid PointAwardSaveParam param, BindingResult errors) {
        //param.setOrgId(SecurityContextHolder.getOrgId());
        param.setOrgId(SecurityContextHolder.getOrgId());
        if (param.getId() == null) {
            return XmResultJson.fail(FAIL_CODE, "缺少id");
        }
        StringBuilder errorStr = new StringBuilder();
        //判断是否有错误值
        if (errors.hasErrors()) {
            errors.getAllErrors().stream().forEach(error -> errorStr.append(error.getDefaultMessage() + ";"));
            if (errorStr.length() > 0) {
                errorStr.deleteCharAt(errorStr.length() - 1);
            }
            return XmResultJson.fail(FAIL_CODE, errorStr.toString());
        }

        AwardAwardBO awardAward = PointAwardSaveParam.createAward(param);

        UpdateAwardDTO serviceParam = new UpdateAwardDTO();
        serviceParam.setAwardAward(awardAward);

        ServiceResult<String> serviceResult = awardDispatcher.updateAward(serviceParam);
        if (serviceResult.isSuccess()) {
            UpdateAwardVO updateAwardVO = new UpdateAwardVO();
            updateAwardVO.setId(serviceResult.getData());
            return XmResultJson.success(updateAwardVO);
        } else {
            return XmResultJson.fail(serviceResult.getErrorData(), serviceResult.getMsg());
        }
    }

//    /**
//     * 删除
//     *
//     * @param id id
//     * @return 结果
//     */
//    @DeleteMapping("/{id}")
//    public XmResultJson<DeleteAwardVO> delete(@PathVariable("id") String id, @RequestBody DeleteParam param) {
//
//        param.setOrgId(SecurityContextHolder.getOrgId());
//
//        if (StringUtils.isAnyBlank(id, param.getOrgId())) {
//            return XmResultJson.fail(FAIL_CODE, "缺少id ,orgId必填参数");
//        }
//
//        DeleteAwardDTO serviceParam = new DeleteAwardDTO();
//        serviceParam.setAwardId(id);
//        serviceParam.setOrgId(param.getOrgId());
//        ServiceResult<Integer> result = awardDispatcher.deleteAward(serviceParam);
//        if (result.isSuccess()) {
//            DeleteAwardVO deleteAwardVO = new DeleteAwardVO();
//            deleteAwardVO.setCount(result.getData());
//            return XmResultJson.success(deleteAwardVO);
//        } else {
//            return XmResultJson.fail(FAIL_CODE, result.getMsg());
//        }
//
//    }


    /**
     * 领取品牌积分
     *
     * @param param param
     * @return 结果
     */
    @PutMapping("/draw")
    public XmResultJson<BandPointDrawVO> draw(@RequestBody @Validated BandPointDrawParam param, BindingResult errors) {

        StringBuilder errorStr = new StringBuilder();
        //判断是否有错误值
        if (errors.hasErrors()) {
            errors.getAllErrors().stream().forEach(error -> {
                errorStr.append(error.getDefaultMessage()).append(";");
            });
            if (errorStr.length() > 0) {
                errorStr.deleteCharAt(errorStr.length() - 1);
            }
            return XmResultJson.fail(FAIL_CODE, errorStr.toString());
        }

        ServiceResult<BandPointDrawBO> result = pointAwardDrawService.drawPointAward(param.getRequestId(), param.getAwardId(), param.getPhone());
        if (result.isSuccess()) {
            BandPointDrawBO bandPointDrawBO = result.getData();
            BandPointDrawVO bandPointDrawVO = new BandPointDrawVO();
            if (bandPointDrawBO != null) {
                BeanUtils.copyProperties(bandPointDrawBO, bandPointDrawVO);
            }
            return XmResultJson.success(bandPointDrawVO);
        } else {
            return XmResultJson.fail(FAIL_CODE, result.getMsg());
        }

    }

    /**
     * 积分奖励统计
     *
     * @param id id
     * @return 结果
     */
    @GetMapping("/{id}/stats")
    XmResultJson<PointAwardStatisVO> stats(@PathVariable("id") String id) {

        ServiceResult<PointAwardStatisBO> serviceGetResult = pointAwardDrawService.stats(id);
        if (serviceGetResult.isSuccess()) {
            PointAwardStatisBO pointAwardStatisBO = serviceGetResult.getData();
            PointAwardStatisVO pointAwardStatisVO = new PointAwardStatisVO();
            if (pointAwardStatisBO != null) {
                BeanUtils.copyProperties(pointAwardStatisBO, pointAwardStatisVO);
            } else {
                pointAwardStatisVO.setCount(0L);
                pointAwardStatisVO.setAmount(0L);
            }
            return XmResultJson.success(pointAwardStatisVO);
        } else {
            return XmResultJson.fail(FAIL_CODE, serviceGetResult.getMsg());
        }
    }

    /**
     * 积分奖励中奖明细
     *
     * @param param 参数
     * @return 结果
     */
    @GetMapping("/lists")
    XmResultJson<PointAwardWinListVO> lists(@Validated PointAwardWinListParam param,
                                            @RequestParam(value = "award_id", required = false) String awardId,
                                            @RequestParam(value = "deliver_channel", required = false) Integer deliverChannel, BindingResult errors) {
        XmResultJson preCheckReuslt = checkListParam(param, awardId, deliverChannel, errors);
        if (preCheckReuslt.getCode() != 0) {
            return preCheckReuslt;
        }

        ServiceResult<PointAwardWinListBO> serviceGetResult = pointAwardDrawService.lists(param);
        if (serviceGetResult.isSuccess()) {
            PointAwardWinListBO pointAwardWinListBO = serviceGetResult.getData();
            PointAwardWinListVO pointAwardWinListVO = new PointAwardWinListVO();
            if (pointAwardWinListBO == null) {
                return XmResultJson.success(pointAwardWinListVO);
            }
            BeanUtils.copyProperties(pointAwardWinListBO, pointAwardWinListVO);

            List<PointAwardWinListBO.PointAwardWin> rows = pointAwardWinListBO.getRows();
            List<PointAwardWinListVO.PointAwardWin> voRows = new ArrayList<>();
            if (rows != null) {
                for (PointAwardWinListBO.PointAwardWin boWin : rows) {
                    if (boWin != null) {
                        PointAwardWinListVO.PointAwardWin voWin = new PointAwardWinListVO.PointAwardWin();
                        BeanUtils.copyProperties(boWin, voWin);
                        voRows.add(voWin);
                    }
                }
            }
            pointAwardWinListVO.setRows(voRows);
            return XmResultJson.success(pointAwardWinListVO);
        } else {
            return XmResultJson.fail(FAIL_CODE, serviceGetResult.getMsg());
        }
    }


    /**
     * 积分奖励中奖明细
     *
     * @param param 参数
     * @return 结果
     */
    @GetMapping("/export")
    XmResultJson<FileInfoVO> export(@Validated PointAwardWinListParam param,
                                    @RequestParam(value = "award_id", required = false) String awardId,
                                    @RequestParam(value = "deliver_channel", required = false) Integer deliverChannel,
                                    BindingResult errors) {
        XmResultJson preCheckReuslt = checkListParam(param, awardId, deliverChannel, errors);
        if (preCheckReuslt.getCode() != 0) {
            return preCheckReuslt;
        }

        ServiceResult<FileInfoDTO> serviceGetResult = pointAwardDrawService.export(param);
        if (serviceGetResult.isSuccess()) {
            FileInfoDTO fileInfoDTO = serviceGetResult.getData();
            FileInfoVO fileInfoVO = new FileInfoVO();
            if (fileInfoDTO != null) {
                BeanUtils.copyProperties(fileInfoDTO, fileInfoVO);
            }
            return XmResultJson.success(fileInfoVO);
        } else {
            return XmResultJson.fail(FAIL_CODE, serviceGetResult.getMsg());
        }
    }

    private XmResultJson checkListParam(PointAwardWinListParam param,
                                        String awardId,
                                        Integer deliverChannel, BindingResult errors) {
        param.setAwardId(awardId);
        param.setDeliverChannel(deliverChannel);

        if (StringUtils.isBlank(awardId)) {
            return XmResultJson.fail(FAIL_CODE, "奖励id不能为空");
        }
        if (!StringUtil.checkObjectId(awardId)) {
            return XmResultJson.fail(FAIL_CODE, "奖励id格式错误");
        }

        StringBuilder errorStr = new StringBuilder();
        //判断是否有错误值
        if (errors.hasErrors()) {
            errors.getAllErrors().stream().forEach(error -> errorStr.append(error.getDefaultMessage() + ";"));
            if (errorStr.length() > 0) {
                errorStr.deleteCharAt(errorStr.length() - 1);
            }
            return XmResultJson.fail(FAIL_CODE, errorStr.toString());
        }
        return XmResultJson.success();
    }


}